package com.gzj.environment.module.collectData.handler;

import com.gzj.environment.enums.collectData.CollectDataTypeEnum;
import com.gzj.environment.model.collectData.dto.AirCollectData;
import com.gzj.environment.module.collectData.repository.AirCollectDataRepository;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

@Component
@Slf4j
public class InsertDataHandler implements InitializingBean {

    private ThreadPoolExecutor threadPoolExecutor;

    private final BlockingQueue<InsertTask> insertDataQueue = new LinkedBlockingQueue<>();

    @Autowired
    private AirCollectDataRepository airCollectDataRepository;

    @Override
    public void afterPropertiesSet() throws Exception {
        threadPoolExecutor = new ThreadPoolExecutor(10, 20, 10,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory());
        threadPoolExecutor.execute(new AirCollectDataInsertTask());
    }

    /**
     * 任务实体
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class InsertTask {
        private CollectDataTypeEnum type;
        private Object collectData;
    }

    /**
     * 添加新增任务
     * @param task 任务
     */
    public void addTask(InsertTask task) {
        try {
            insertDataQueue.put(task);
        } catch (InterruptedException e) {
            log.error("添加新增任务时发生异常", e);
        }
    }

    /**
     * 新增空气站数据的线程
     */
    private class AirCollectDataInsertTask implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    log.info("正在读取需要新增的空气站采集数据");
                    InsertTask task = insertDataQueue.take();
                    switch (task.type) {
                        case AIR:
                            airCollectDataRepository.saveAirCollectData((AirCollectData) task.collectData);
                            break;
                        // TODO 留作扩展，其他客户端类型往下面添加即可
                    }

                } catch (Exception e) {
                    log.error("新增空气站采集数据时发生异常", e);
                }
            }
        }
    }
}
